package org.example.util;

import org.activiti.bpmn.converter.BpmnXMLConverter;
import org.activiti.bpmn.model.BpmnModel;
import org.activiti.engine.RepositoryService;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.List;

@Component
public class XMLUtil {
    @Resource
    private RepositoryService repositoryService;

    /**
     * 实现bpmn.xml向mxGraph.xml的转变。
     * 由此可以得出 在进行流程模型定义的时候就是 mxGraph.xml向 bpmn.xml 转变的过程
     * @throws DocumentException
     */
    public String convertXml(String procDefId) throws DocumentException {
        BpmnModel bpmnModel = repositoryService.getBpmnModel(procDefId);
        BpmnXMLConverter converter = new BpmnXMLConverter();
        //把bpmnModel对象转换成字符
        byte[] bytes = converter.convertToXML(bpmnModel);
        String xmlContenxt = new String(bytes);
        Document bpmn = DocumentHelper.parseText(xmlContenxt);

        //活动activity
        Element process = bpmn.getRootElement().elements().get(0);
        Element startEvent = process.element("startEvent");
        Element endEvent = process.element("endEvent");
        List<Element> userTasks = process.elements("userTask");

        //位置
        Element  bpmndiBPMNDiagram = bpmn.getRootElement().elements().get(1);
        Element bpmndiBPMNPlanes = bpmndiBPMNDiagram.elements().get(0);
        List<Element> bpmndiBPMNShapes = bpmndiBPMNPlanes.elements();
        //构造头部
        Document mxGraph = DocumentHelper.createDocument();
        Element mxGraphModel = mxGraph.addElement("mxGraphModel");
        Element root = mxGraphModel.addElement("root");
        Element parent = root.addElement("mxCell");
        parent.addAttribute("id","0");
        Element mxCell2 = root.addElement("mxCell");
        mxCell2.addAttribute("id","1");
        mxCell2.addAttribute("parent","0");
        //构造body
        //插入开始节点
        insertNode(root,startEvent,bpmndiBPMNShapes,1);
        for(Element userTask: userTasks){
            Element mxCell = root.addElement("mxCell");
            mxCell.addAttribute("id",userTask.attribute("id").getValue());
            mxCell.addAttribute("parent","1");
            mxCell.addAttribute("value",userTask.attribute("name").getValue());
            mxCell.addAttribute("style","activityNode");
            mxCell.addAttribute("vertex","1");
            //插入位置
            Element shape = getElementById("BPMNShape_"+userTask.attributeValue("id"),bpmndiBPMNShapes).elements().get(0);
            if(shape != null ) {
                Element mxGeometry = mxCell.addElement("mxGeometry");
                mxGeometry.addAttribute("x", shape.attributeValue("x"));
                mxGeometry.addAttribute("y", shape.attributeValue("y"));
                mxGeometry.addAttribute("width", shape.attributeValue("width"));
                mxGeometry.addAttribute("height", shape.attributeValue("height"));
                mxGeometry.addAttribute("as", "geometry");
            }

        }
        //插入结束节点
        insertNode(root,endEvent,bpmndiBPMNShapes,2);
        //插入线
        List<Element> sequenceFlows = process.elements("sequenceFlow");
        for(Element sequenceFlow: sequenceFlows){
            Element mxCell = root.addElement("mxCell");
            mxCell.addAttribute("id",sequenceFlow.attribute("id").getValue());
            mxCell.addAttribute("parent","1");
            mxCell.addAttribute("edge","1");
            mxCell.addAttribute("source",sequenceFlow.attribute("sourceRef").getValue());
            mxCell.addAttribute("target",sequenceFlow.attribute("targetRef").getValue());
            Element mxGeometry = mxCell.addElement("mxGeometry");
            mxGeometry.addAttribute("relative","1");
            mxGeometry.addAttribute("as","geometry");
        }
       return mxGraph.asXML();
    }

    //根据id获取元素
    Element getElementById(String id, List<Element> list ){
        Element element = null;
        for(Element e: list){
            String eid = e.attributeValue("id");
            if(id.equals(eid)){
                element = e;
                break;
            }
        }
        return element;
    }

    /**
     * 插入开始节点和结束节点
     * @param root
     * @param node
     */
    void insertNode(Element root, Element node, List<Element> shapes,Integer type){
        Element mxCell = root.addElement("mxCell");
        mxCell.addAttribute("parent","1");
        mxCell.addAttribute("id",node.attribute("id").getValue());
        mxCell.addAttribute("value",node.attribute("name").getValue());
        mxCell.addAttribute("vertex","1");
        if(type == 1) {
            mxCell.addAttribute("style", "startNode");
        }else {
            mxCell.addAttribute("style", "endNode");
        }
        //插入位置
        Element shape = getElementById("BPMNShape_"+node.attributeValue("id"),shapes).elements().get(0);
        if(shape != null ) {
            Element mxGeometry = mxCell.addElement("mxGeometry");
            mxGeometry.addAttribute("x", shape.attributeValue("x"));
            mxGeometry.addAttribute("y", shape.attributeValue("y"));
            mxGeometry.addAttribute("width", shape.attributeValue("width"));
            mxGeometry.addAttribute("height", shape.attributeValue("height"));
            mxGeometry.addAttribute("as", "geometry");
        }

    }
}
